package com.yeskery.nut.core;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 系统默认的线程池
 * @author sprout
 * @version 1.0
 * 2021-02-23 17:51
 */
public class DefaultThreadPool implements ThreadPool {

    /** 定时调度执行服务 */
    private volatile ScheduledExecutorService scheduledexecutorService;

    /** 执行服务 */
    private volatile ExecutorService executorService;

    @Override
    public ScheduledExecutorService getScheduledThreadPool() {
        if (scheduledexecutorService == null) {
            synchronized (this) {
                if (scheduledexecutorService == null) {
                    int processor = Runtime.getRuntime().availableProcessors();
                    scheduledexecutorService = new ScheduledThreadPoolExecutor(processor * 2,
                            new DefaultThreadFactory(true), new ThreadPoolExecutor.AbortPolicy());
                }
            }
        }
        return scheduledexecutorService;
    }

    /**
     * 获取默认的线程池
     * @return 线程池对象
     */
    @Override
    public ExecutorService getThreadPool() {
        if (executorService == null) {
            synchronized (this) {
                if (executorService == null) {
                    int processor = Runtime.getRuntime().availableProcessors();
                    executorService = new ThreadPoolExecutor(processor * 2, processor * 10,
                            0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(1024),
                            new DefaultThreadFactory(false), new ThreadPoolExecutor.AbortPolicy());
                }
            }
        }
        return executorService;
    }

    @Override
    public void close() {
        if (scheduledexecutorService != null) {
            scheduledexecutorService.shutdown();
        }
        if (executorService != null) {
            executorService.shutdown();
        }
    }

    /**
     * 默认的线程工厂
     * @author sprout
     * @version 1.0
     * 2021-02-23 17:55
     */
    static class DefaultThreadFactory implements ThreadFactory {
        /** 线程池编号 */
        private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
        /** 线程池分组 */
        private final ThreadGroup group;
        /** 线程编号 */
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        /** 线程名称前缀 */
        private final String namePrefix;

        /**
         * 构建一个默认的线程工厂
         * @param scheduled 是否是定时调度的线程池服务
         */
        DefaultThreadFactory(boolean scheduled) {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                    Thread.currentThread().getThreadGroup();
            namePrefix = "nut" + (scheduled ? "[s]-" : "-") +
                    POOL_NUMBER.getAndIncrement() +
                    "-thread-";
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                    namePrefix + threadNumber.getAndIncrement(),
                    0);
            if (t.isDaemon()) {
                t.setDaemon(false);
            }
            if (t.getPriority() != Thread.NORM_PRIORITY) {
                t.setPriority(Thread.NORM_PRIORITY);
            }
            return t;
        }
    }
}
